package com.jn.erp.wechat.student.api.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jn.erp.common.core.result.AjaxResult;
import com.jn.erp.security.entity.LoginUser;
import com.jn.erp.security.entity.SysUser;
import com.jn.erp.security.service.TokenService;
import com.jn.erp.security.utils.SecurityUtils;
import com.jn.erp.web.api.student.entity.Student;
import com.jn.erp.web.api.student.entity.StudentContactsUser;
import com.jn.erp.web.api.student.entity.StudentUser;
import com.jn.erp.web.api.student.service.StudentContactsUserService;
import com.jn.erp.web.api.student.service.StudentService;
import com.jn.erp.web.api.student.service.StudentUserService;
import com.jn.erp.web.api.student.utils.BizException;
import com.jn.erp.wechat.student.config.Mini2AppConfig;
import com.jn.erp.wechat.common.api.entity.WxAccess;
import com.jn.erp.wechat.common.api.entity.dto.WxMaLoginDto;
import com.jn.erp.wechat.common.api.service.WxAccessService;
import com.jn.erp.security.utils.WxsUtils;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * <pre>
 *  家长端登录
 * </pre>
 *
 * @author sunjiyong
 * @since 2024/9/9 9:08
 */
@AllArgsConstructor
@RestController
@RequestMapping("/smp")
public class StudentMpLoginController {
    @Autowired
    private Mini2AppConfig mini2AppConfig;

    private final WxMaService wxMaService;

    @Autowired
    public StudentMpLoginController(@Qualifier("parentWxMaService") WxMaService wxMaService){
        this.wxMaService = wxMaService;
    }
    @Autowired
    private WxAccessService wxAccessService;
    @Autowired
    private StudentUserService studentUserService;
    @Autowired
    private StudentContactsUserService studentContactsUserService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private TokenService tokenService;

    //设置家长按钮权限permissions为student:parents,wxs:operate:list,wxs:operate:edit,wxs:operate:add,wxs:operate:delete
    private static Set<String> WXS_PERMISSIONS= Stream.of(WxsUtils.WXS_PERMISSIONS)
            .collect(Collectors.toSet());

    //绑定家长
    @PostMapping("/bind")
    @Transactional
    public AjaxResult bind(@RequestBody WxMaLoginDto loginDto) {
        String appid = mini2AppConfig.getAppId();
        if (StringUtils.isBlank(loginDto.getMobile())) {
            return AjaxResult.error("缺少参数手机号");
        }
        if (StringUtils.isBlank(loginDto.getCode())) {
            return AjaxResult.error("缺少参数code");
        }
        if (!this.wxMaService.switchover(appid)) {
            return AjaxResult.error("未找到对应appid=" + appid + "的配置，请核实！");
        }

        QueryWrapper<StudentUser> qw = new QueryWrapper<>();
        qw.eq("mobile", loginDto.getMobile());
        StudentUser one = studentUserService.getOne(qw);
        if (one == null) {
            return AjaxResult.error("预留手机号不匹配");
        }

        WxMaJscode2SessionResult session = loginSession(appid, loginDto.getCode());
        WxAccess wxAccess = wxAccessService.logMpRecord(session,loginDto,"mps");

        if (wxAccess.getId() == null) {
            return AjaxResult.error("数据入库失败");
        }

        UpdateWrapper<StudentUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("wx_access_id", wxAccess.getId());
        updateWrapper.eq("id", one.getId());
        boolean update = studentUserService.update(updateWrapper);
        if (update) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error("数据保存失败");
        }

    }


    //登录获取token
    @PostMapping("/login")
    public AjaxResult login(@RequestBody WxMaLoginDto loginDto) {
        String token = "";
        try {
            String appid = mini2AppConfig.getAppId();
            if (StringUtils.isBlank(loginDto.getCode())) {
                return AjaxResult.error("缺少参数code");
            }
            if (!this.wxMaService.switchover(appid)) {
                return AjaxResult.error("未找到对应appid=" + appid + "的配置，请核实！");
            }
            WxMaJscode2SessionResult session = loginSession(appid, loginDto.getCode());
            WxAccess wxAccess = wxAccessService.logMpRecord(session,loginDto,"mps");

            QueryWrapper<StudentUser> qw = new QueryWrapper<>();
            qw.eq("wx_access_id", wxAccess.getId());
            qw.eq("state", 0);
            StudentUser one = studentUserService.getOne(qw);
            if (one == null) {
                return AjaxResult.success(token);
            }
            token = attemptGetToken(wxAccess.getId());
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.success("操作成功",token);
    }


    //根据登录用户，获取学生信息
    @PostMapping("/studentInfos")
    public AjaxResult studentInfos() {
        Long userId = SecurityUtils.getUserId();
        if (userId != null) {
            QueryWrapper<StudentContactsUser> qw=new QueryWrapper<>();
            qw.eq("user_id",userId);
            List<StudentContactsUser> list = studentContactsUserService.list(qw);
            if(list.size()==0){
                return AjaxResult.error("用户下没有学生信息");
            }
            List<Long> collect = list.stream().map(StudentContactsUser::getStudentId).collect(Collectors.toList());
            QueryWrapper<Student> qws=new QueryWrapper<>();
            qws.in("id", collect.toArray());
            List<Student> infos = studentService.list(qws);
            return AjaxResult.success(infos);
        }
        return AjaxResult.error("未获取登录信息");
    }

    private WxMaJscode2SessionResult loginSession(String appid, String code) {
        try {
            return wxMaService.getUserService().getSessionInfo(code);
        } catch (WxErrorException e) {
            throw new BizException(e.toString());
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }
    /**
     * 尝试获取登录token，当该微信账号没有登录过的时候会获取不到，前端会有提示
     */
    private String attemptGetToken(Long wxAccessId) {
        StudentUser wxuser = wxAccessService.getByWxStudentAccessId(wxAccessId);
        if (wxuser != null) {
            SysUser login=new SysUser();
            login.setId(wxuser.getId());
            login.setName("家长用户");
            LoginUser loginUser = new LoginUser(wxuser.getId(), login, WXS_PERMISSIONS);
            String token = tokenService.createToken(loginUser);
            return token;
        }
        return "";
    }
}
